home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Snippets / AsynchSnd 1.0.3 / AsynchSnd.c < prev    next >
Text File  |  1996-07-07  |  8KB  |  419 lines

  1. /* ----------------------------------------------------------------------
  2.  
  3.     AsynchSnd
  4.     version 1.0.3
  5.     
  6.     This snippet is a demonstration of asynchronous sound playing.
  7.  
  8.     Written by: Ken Long
  9.     Updated for CW9 by: Paul Celestin
  10.     
  11.     950711 - 1.0.1 - ported to CW
  12.     951201 - 1.0.2 - updated for CW7
  13.     960707 - 1.0.3 - updated for CW9
  14.  
  15. ---------------------------------------------------------------------- */
  16.  
  17. #include <Sound.h>
  18.  
  19. MenuHandle    appleMenu, fileMenu, editMenu, widthMenu;
  20.  
  21. enum {
  22.     appleID = 1,
  23.     fileID,
  24.     editID,
  25.     widthID
  26. };
  27.  
  28. enum {
  29.     openItem = 1,
  30.     closeItem,
  31.     quitItem = 4
  32. };
  33.  
  34. #define over qd.screenBits.bounds.right
  35. #define down qd.screenBits.bounds.bottom
  36.  
  37. WindowPtr    shellWindow;
  38. Rect        dragRect;
  39. Rect        windowBounds;
  40. Rect        circleStart = {2, 2, 296, 296};
  41. int            theWidth = 2;
  42.  
  43. SndChannelPtr channelPtr;
  44.  
  45. //• Prototypes:
  46. void SetUpWindow (void);
  47. void Center (char *str);
  48. void SetText (short font, short size, short style);
  49. void DoAbout (void);
  50. void DrawBullseye (short active);
  51. void DoTheSound (short whichID, Boolean asynch);
  52. void HandleKeyHits (EventRecord *theEvent);
  53. void SetUpMenus (void);
  54. void AdjustMenus (void);
  55. int enable (MenuHandle menu, short item, short ok);
  56. void HandleMenu (long mSelect);
  57. void InitMacintosh (void);
  58. void HandleMouseDown (EventRecord *theEvent);
  59. void HandleEvent (void);
  60. void main (void);
  61.  
  62. //• Routines:
  63.  
  64. void SetUpWindow(void)
  65. {
  66.     dragRect = qd.screenBits.bounds;
  67.     
  68.     SetRect (&windowBounds, over / 2 - 150,
  69.                             down / 2 - 150,
  70.                             over / 2 + 150,
  71.                             down / 2 + 150);
  72.                             
  73.     shellWindow = NewWindow(0L, &windowBounds, "\pAsynchSnd", true, noGrowDocProc, (WindowPtr) -1L, true, 0);
  74.     SetPort(shellWindow);
  75. }
  76.  
  77. void Center (char *str)
  78. {    
  79.     Move ((((circleStart.right - 2) / 2) -
  80.             (StringWidth ((StringPtr) str)) / 2), 0);
  81.     DrawString ((StringPtr) str);
  82.     Move (-(shellWindow->pnLoc.h), (shellWindow->txSize) + 2);
  83. }
  84.  
  85. void SetText (short font, short size, short style)
  86. {
  87.     TextFont (font);
  88.     TextSize (size);
  89.     TextFace (style);
  90. }
  91.  
  92. void DoAbout ()
  93. {
  94.     EraseRect (&circleStart);
  95.     MoveTo (0, 0);
  96.     Move (0, 30);
  97.     SetText (geneva, 12, italic);
  98.     Center ((char*) "\pThis is a demo of asynchronous sound play.");
  99.     Move (0, 5);
  100.     SetText (times, 12, outline);
  101.     Center ((char*) "\pUpdated for CW9 on 7 July 1996");
  102.     Move (0, 15);
  103.     SetText (0, 12, 0);
  104.     Center ((char*) "\pClick the mouse for some more bull!");
  105.     Move (0, 5);
  106.     Center ((char*) "\pHit number keys as fast as you can.");
  107.     Move (0, 5);
  108.     Center ((char*) "\pHold keys down for continuous sound.");
  109. }
  110.     
  111. void DrawBullseye(short active)
  112. {
  113.     Rect    myRect;
  114.     int        color = true;
  115.     
  116.     SetPort(shellWindow);
  117.     EraseRect(&circleStart);
  118.     myRect = circleStart;
  119.     
  120.     while(myRect.left < myRect.right)
  121.     {
  122.         FrameOval(&myRect);//, color ? (active ? black : gray) : white);
  123. //•     FillOval(&myRect, color ? (active ? black : gray) : white);
  124.         InsetRect(&myRect, theWidth, theWidth);
  125. //•        color = !color;
  126.     } 
  127. }
  128.  
  129. //• The following routine was added by K.A.L.  It was from the Stella 
  130. //• Obscura source, by John Calhoun and ported to C by Ken Long.
  131.  
  132. void DoTheSound (short whichID, Boolean asynch)
  133. {
  134.     Handle theSnd;
  135.     OSErr err;
  136.     Boolean soundActive;
  137.     
  138.     soundActive = true;    
  139.     
  140.     if ((soundActive))
  141.     {
  142.         theSnd = GetResource ('snd ', whichID);
  143.         
  144.         if ((theSnd != 0L) && (ResError () == noErr))
  145.         {
  146.             if ((channelPtr != 0L))
  147.             {
  148.                 err = SndDisposeChannel (channelPtr, true);
  149.                 channelPtr = 0L;
  150.             }
  151.             if ((asynch == true) && 
  152.                 (SndNewChannel 
  153.                 (&channelPtr, 0, initMono, 0L) == noErr)) 
  154.                 err = SndPlay (channelPtr, (SndListHandle)theSnd, true); 
  155.             else    
  156.                 err = SndPlay (0L, (SndListHandle)theSnd, false);
  157.         }
  158.     }
  159. }
  160.  
  161. //• I added this routine to add key hit sound play capability.
  162. void HandleKeyHits (EventRecord *theEvent)
  163. {
  164.     short    chCode;
  165.     long ticks;
  166.     
  167.     chCode = theEvent->message & charCodeMask;
  168.  
  169.     switch (chCode) 
  170.     {
  171.         case '1':  // User hits the 1 key.
  172.                DoTheSound (9001, true);  // '9001' matches res.ID.
  173.         break;
  174.  
  175.         case '2': 
  176.                DoTheSound (9002, true);
  177.         break;
  178.  
  179.         case '3':
  180.                DoTheSound (9003, true);
  181.         break;
  182.  
  183.         case '4':
  184.                DoTheSound (9004, true);
  185.         break;
  186.  
  187.         case '5':
  188.                DoTheSound (9005, true);
  189.         break;
  190.  
  191.         case '6':
  192.                DoTheSound (9006, true);
  193.         break;
  194.  
  195.         case '7':
  196.                DoTheSound (9007, true);
  197.         break;
  198.  
  199.         case '8':
  200.                DoTheSound (9008, true);
  201.         break;
  202.  
  203.         case '9':
  204.                DoTheSound (9009, true);
  205.         break;
  206.  
  207.         case '0':
  208.                DoTheSound (9010, true);
  209.         break;
  210.     }
  211. }
  212.  
  213. void SetUpMenus(void)
  214. {
  215.     InsertMenu(appleMenu = NewMenu(appleID, "\p\024"), 0);
  216.     InsertMenu(fileMenu = NewMenu(fileID, "\pFile"), 0);
  217.     InsertMenu(editMenu = NewMenu(editID, "\pEdit"), 0);
  218.     InsertMenu(widthMenu = NewMenu(widthID, "\pWidth"), 0);
  219.     DrawMenuBar();
  220.     AppendMenu(appleMenu, "\pWhat about it?");
  221.     AddResMenu(appleMenu, 'DRVR');
  222.     AppendMenu(fileMenu, "\pOpen/O;Close/W;(-;Quit/Q");
  223.     AppendMenu(editMenu, "\pUndo/Z;(-;Cut/X;Copy/C;Paste/V;Clear");
  224.     AppendMenu(widthMenu, "\p1/1;2/2;3/3;4/4;5/5;6/6;7/7;8/8;9/9");
  225. }
  226.  
  227. void AdjustMenus(void)
  228. {
  229.     register WindowPeek wp = (WindowPeek) FrontWindow();
  230.     short kind = wp ? wp->windowKind : 0;
  231.     Boolean DA = kind < 0;
  232.     
  233.     enable(editMenu, 1, DA);
  234.     enable(editMenu, 3, DA);
  235.     enable(editMenu, 4, DA);
  236.     enable(editMenu, 5, DA);
  237.     enable(editMenu, 6, DA);
  238.     
  239.     enable(fileMenu, openItem, !((WindowPeek) shellWindow)->visible);
  240.     enable(fileMenu, closeItem, DA || ((WindowPeek) shellWindow)->visible);
  241.  
  242.     CheckItem(widthMenu, theWidth, true);
  243. }
  244.  
  245. int enable(MenuHandle menu, short item, short ok)
  246. {
  247.     if (ok)
  248.         EnableItem(menu, item);
  249.     else
  250.         DisableItem(menu, item);
  251. }
  252.  
  253. void HandleMenu (long mSelect)
  254. {
  255.     int            menuID = HiWord(mSelect);
  256.     int            menuItem = LoWord(mSelect);
  257.     Str255        name;
  258.     GrafPtr        savePort;
  259.     WindowPeek    frontWindow;
  260.     
  261.     switch (menuID)
  262.     {
  263.         case appleID:
  264.             if (menuItem == 1)
  265.                 DoAbout ();
  266.             else
  267.                 {
  268.                     GetPort(&savePort);
  269.                     GetItem(appleMenu, menuItem, name);
  270.                     OpenDeskAcc(name);
  271.                     SetPort(savePort);
  272.             }
  273.         break;
  274.     
  275.         case fileID:
  276.         switch (menuItem)
  277.         {
  278.             case openItem:
  279.                 ShowWindow(shellWindow);
  280.                 SelectWindow(shellWindow);
  281.             break;
  282.                                   
  283.             case closeItem:
  284.                 if ((frontWindow = (WindowPeek) FrontWindow()) == 0L)
  285.                     break;
  286.                     
  287.                 if (frontWindow->windowKind < 0)
  288.                     CloseDeskAcc(frontWindow->windowKind);
  289.                 else if (frontWindow = (WindowPeek) shellWindow)
  290.                     HideWindow(shellWindow);
  291.               break;
  292.                           
  293.             case quitItem:
  294.                 ExitToShell();
  295.             break;
  296.         }
  297.         break;
  298.                   
  299.         case editID:
  300.         if (!SystemEdit(menuItem-1))
  301.             SysBeep(5);
  302.         break;
  303.         
  304.         case widthID:
  305.             CheckItem(widthMenu, theWidth, false);
  306.             theWidth = menuItem;
  307.             InvalRect(&shellWindow->portRect);
  308.         break;
  309.     }
  310. }
  311.  
  312. void InitMacintosh(void)
  313. {
  314.     MaxApplZone();
  315.     
  316.     InitGraf(&qd.thePort);
  317.     InitFonts();
  318.     FlushEvents(everyEvent, 0);
  319.     InitWindows();
  320.     InitMenus();
  321.     TEInit();
  322.     InitDialogs(0L);
  323.     InitCursor();
  324. }
  325.  
  326. void HandleMouseDown (EventRecord    *theEvent)
  327. {
  328.     WindowPtr    theWindow;
  329.     int            windowCode = FindWindow (theEvent->where, &theWindow);
  330.     long ticks;
  331.     
  332.     switch (windowCode)
  333.     {
  334.         case inSysWindow: 
  335.             SystemClick (theEvent, theWindow);
  336.         break;
  337.             
  338.         case inMenuBar:
  339.             AdjustMenus();
  340.             HandleMenu(MenuSelect(theEvent->where));
  341.         break;
  342.             
  343.         case inDrag:
  344.             if (theWindow == shellWindow)
  345.                 DragWindow(shellWindow, theEvent->where, &dragRect);
  346.         break;
  347.                 
  348.         case inContent:
  349.             if (theWindow == shellWindow)
  350.             {
  351.                 if (theWindow != FrontWindow())
  352.                     SelectWindow(shellWindow);
  353.                 else
  354.                     InvalRect(&shellWindow->portRect);
  355.             }
  356.             DoTheSound (8999, true);    //• <-----Added by K.A.L.
  357.         break;
  358.             
  359.         case inGoAway:
  360.             if (theWindow == shellWindow && 
  361.                 TrackGoAway(shellWindow, theEvent->where))
  362.             ExitToShell ();
  363. //            HideWindow(shellWindow);
  364.         break;
  365.     }
  366. }
  367.  
  368. void HandleEvent(void)
  369. {
  370.     int            ok;
  371.     EventRecord    theEvent;
  372.  
  373.     HiliteMenu(0);
  374.     SystemTask ();        /* Handle desk accessories */
  375.     
  376.     ok = GetNextEvent (everyEvent, &theEvent);
  377.     if (ok)
  378.         switch (theEvent.what)
  379.         {
  380.             case mouseDown:
  381.                 HandleMouseDown(&theEvent);
  382.             break;
  383.                 
  384.             case keyDown: 
  385.             case autoKey:
  386.                 if ((theEvent.modifiers & cmdKey) != 0)
  387.                 {
  388.                     AdjustMenus();
  389.                     HandleMenu(MenuKey((char) (theEvent.message & charCodeMask)));
  390.                 }
  391.                 else
  392.                     HandleKeyHits (&theEvent);
  393.             break;
  394.                 
  395.             case updateEvt:
  396.                 BeginUpdate(shellWindow);
  397.                 DrawBullseye(((WindowPeek) shellWindow)->hilited);
  398.                 EndUpdate(shellWindow);
  399.             break;
  400.                     
  401.             case activateEvt:
  402.                 InvalRect(&shellWindow->portRect);
  403.             break;
  404.         }
  405. }
  406.  
  407. void main(void)
  408. {
  409.     long tiks;
  410.     
  411.     InitMacintosh();
  412.     SetUpMenus();
  413.     SetUpWindow();
  414.     DoAbout ();
  415.     Delay (180L, &tiks);
  416.     for (;;)
  417.         HandleEvent();
  418. }
  419.